package net.qhzw.geologr5.gis.service.system.service.impl;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import net.qhzw.geologr5.gis.common.framework.utils.JsonResult;
import net.qhzw.geologr5.gis.common.framework.utils.StringUtils;
import net.qhzw.geologr5.gis.common.redis.utils.RedisUtils;
import net.qhzw.geologr5.gis.service.system.component.FileTemplate;
import net.qhzw.geologr5.gis.service.system.entity.ProjectData;
import net.qhzw.geologr5.gis.service.system.excel.DataSheet;
import net.qhzw.geologr5.gis.service.system.file2linux.ExtractUtils;
import net.qhzw.geologr5.gis.service.system.file2linux.SFTPUtil;
import net.qhzw.geologr5.gis.service.system.mapper.ProjectDataMapper;
import net.qhzw.geologr5.gis.service.system.service.ProjectService;
import net.qhzw.geologr5.gis.service.system.utils.TimeSimpleUtil;
import net.qhzw.geologr5.gis.service.system.utils.UUIDUtil;
import net.qhzw.geologr5.gis.service.system.vo.project.DataSheetVo;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

@Service
@Slf4j
public class ProjectServiceImpl implements ProjectService {

    @Autowired
    private ProjectDataMapper projectDataMapper;


    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private FileTemplate fileTemplate;


    @Autowired
    private SqlSessionTemplate sqlSessionTemplate;


    @Value("${fileServer.fileUrl}")
    private String fileUrl; //项目资料上传nginx配置的静态资源

    /***
     * 上传文件存放服务器地址
     */
    private final String fastDFSPath = "/opt/fastdfs/fdfs_storage/data/";

    /***
     * 导入excel
     * @param file
     * @return
     */
    @Override
    public JsonResult importExcel(MultipartFile file, Integer projectId) {
        log.info("导入excel文件名称: [{}]", file.getOriginalFilename());
        Map<String, Object> result = new HashMap<>();
        try {
            ImportParams params = new ImportParams();
            params.setTitleRows(1);//设置一级标题行为1行
            params.setHeadRows(1);//设置header标题为1行
            List<DataSheet> dataSheetList = ExcelImportUtil.importExcel(file.getInputStream(), DataSheet.class, params);
            if (dataSheetList.isEmpty()) {
                return JsonResult.error("表格数据为空");
            }
            log.info("dataSheetList: {}", JSON.toJSONString(dataSheetList));
            //将数据存入缓存
            String sign = UUIDUtil.getRandNum(6);
            redisUtils.setCacheObject("sign", sign);
            redisUtils.setCacheMapValue("dataSheetList", sign, JSON.toJSONString(dataSheetList));
            if (redisUtils.getCacheObject("projectId") != null) {
                redisUtils.deleteObject("projectId");
            }
            redisUtils.setCacheObject("projectId", projectId);
            result.put("dataSheetList", dataSheetList);
            result.put("sign", sign);
            return JsonResult.success(result);
        } catch (Exception e) {
            log.error("导入excel失败==ProjectServiceImpl==method:importExcel==errMsg: {}", e.getMessage());
            return JsonResult.error(e.getMessage());
        }
    }


    /***
     * 项目资料上传
     * @param file
     * @param sign 标识
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult upload(MultipartFile file, String sign) {
        log.info("项目资料上传==ProjectServiceImpl==method:upload==文件名: {}, 文件大小: {}", file.getOriginalFilename(), file.getSize());
        Map<String, Object> result = new HashMap<>();
        //返回前端展示的相对路径
        List<DataSheet> sheetList = new ArrayList<>();
        List<DataSheetVo> projectDataList = new ArrayList<>();
        List<DataSheetVo> dataSheetVoList = new ArrayList<>();
        try {
            //excel上传之后的资料
            String dataSheetJson = redisUtils.getCacheMapValue("dataSheetList", sign);
            if (StringUtils.isEmpty(dataSheetJson)) {
                return JsonResult.error("请重新上传Excel");
            }
            List<DataSheet> dataSheetList = JSONObject.parseArray(dataSheetJson, DataSheet.class);
            //测试上传文件并解压
            String filePath = fileTemplate.uploadFile(file);
            if (StringUtils.isEmpty(filePath)) {
                return JsonResult.error("资料上传失败");
            }
            Map<String, String> paramMap = subFilePath(filePath);
            String fileName = paramMap.get("fileName");
            String relativePath = paramMap.get("path");
            String fileUrl = fastDFSPath + relativePath;
            log.info("上传后的路径: {}", fileUrl);
            //解压文件
            //创建解压文件夹
            String randomString = UUIDUtil.getRandomString(8); //随机文件夹
            String temPath = "/opt/upload/unZipDir/" + TimeSimpleUtil.getTimeStr() + "/";
            String unZipDir = temPath + randomString + "/";
            if (!SFTPUtil.isExistDir(temPath)) {
                SFTPUtil.mkdir(temPath);
            }
            if (!SFTPUtil.isExistDir(unZipDir)) {
                Boolean mkdir1 = SFTPUtil.mkdir(unZipDir);
                if (!mkdir1) {
                    return JsonResult.error("服务器创建解压文件夹错误");
                }
            }
            //解压文件
            Map<String, Object> resultMap = ExtractUtils.remoteZipToFile(fileUrl, fileName, unZipDir);
            Boolean status = (Boolean) resultMap.get("status");
            List<String> dirList = (List<String>) resultMap.get("dirList");
            if (!status) {
                return JsonResult.error("服务器解压文件出错");
            }
            //解压后的路径
            List<String> filePathList = conversion(dirList, unZipDir);
            System.out.println("filePathList: " + filePathList);
            //匹配路径
            for (String path : filePathList) {
                for (DataSheet dataSheet : dataSheetList) {
                    if (!StringUtils.isEmpty(dataSheet.getFilePath())) {
                        if (dataSheet.getFilePath().contains(path)) {
                            DataSheet succSheet = new DataSheet();
                            succSheet.setFilePath(dataSheet.getFilePath());
                            //访问路径
                            succSheet.setFileUrl(this.fileUrl + unZipDir.substring(4, unZipDir.length()) + path);
                            succSheet.setFileName(dataSheet.getFileName());
                            succSheet.setAuthority(dataSheet.getAuthority());
                            DataSheetVo sheetVo = new DataSheetVo();
                            BeanUtils.copyProperties(succSheet, sheetVo);
                            sheetVo.setRecordState("有");
                            sheetVo.setFileStatus("有");
                            sheetVo.setContrastResult("成功");
                            dataSheetVoList.add(sheetVo);
                            sheetList.add(succSheet);
                        } else {
                            DataSheet errSheet = new DataSheet();
                            errSheet.setFilePath(dataSheet.getFilePath());
                            errSheet.setFileName(dataSheet.getFileName());
                            errSheet.setAuthority(dataSheet.getAuthority());
                            DataSheetVo sheetVo = new DataSheetVo();
                            BeanUtils.copyProperties(errSheet, sheetVo);
                            sheetVo.setRecordState("无");
                            sheetVo.setFileStatus("无");
                            sheetVo.setContrastResult("失败");
                            dataSheetVoList.add(sheetVo);
                        }
                    }
                }
            }
            for (int i = 0; i < dataSheetVoList.size(); i++) {
                DataSheetVo sheetVo = dataSheetVoList.get(i);
                sheetVo.setId(i + 1);
                projectDataList.add(sheetVo);
            }
            result.put("verify", randomString);
            redisUtils.setCacheMapValue("sheetList", randomString, JSON.toJSONString(sheetList));
            result.put("projectDataList", projectDataList);
            return JsonResult.success(result);
        } catch (Exception e) {
            log.error("文件上传失败==ProjectServiceImpl==method:upload==errMsg: {}", e.getMessage());
            return JsonResult.error(e.getMessage());
        }
    }


    /****
     * 项目资料上传
     * @param file
     * @param sign 标识
     * @return
     */
    /*@Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult upload(MultipartFile file, String sign) {
        log.info("项目资料上传==ProjectServiceImpl==method:upload==文件名: {}, 文件大小: {}", file.getOriginalFilename(), file.getSize());
        //返回前端展示的相对路径
        Set<String> successPath = new HashSet<>();
        Set<String> errPath = new HashSet<>();
        Map<String, Object> result = new HashMap<>();
        //存放解压成功后的路径
        Set<String> pathList = new HashSet<>();
        Set<String> list = new HashSet<>();
        try {
            //获取redis存放的数据 匹配Excel导入的文件路径
            String dataSheetJson = redisUtils.getCacheMapValue("dataSheetList", sign);
            if (StringUtils.isEmpty(dataSheetJson)) {
                return JsonResult.error("请重新上传Excel");
            }

            String timeStr = TimeSimpleUtil.getTimeStr();
            String dir = "/opt/upload/" + timeStr + "/";
            //创建文件夹
            if (!SFTPUtil.isExistDir(dir)) {
                Boolean mkdir = SFTPUtil.mkdir(dir);
                if (!mkdir) {
                    return JsonResult.error("服务器创建文件夹错误");
                }
            }
            //文件上传到服务器
            File newFile = this.multipartFileToFile(file);
            Boolean aBoolean = SFTPUtil.uploadFile(dir, newFile);
            delteTempFile(newFile);
            if (!aBoolean) {
                return JsonResult.error("上传失败");
            }
            //创建解压文件夹
            String unZipDir = "/opt/upload/unZipDir/" + TimeSimpleUtil.getTimeStr();
            if (!SFTPUtil.isExistDir(unZipDir)) {
                Boolean mkdir1 = SFTPUtil.mkdir(unZipDir);
                if (!mkdir1) {
                    return JsonResult.error("服务器创建解压文件夹错误");
                }
            }
            //解压文件
            Map<String, Object> resultMap = ExtractUtils.remoteZipToFile(dir, file.getOriginalFilename(), unZipDir);
            Boolean status = (Boolean) resultMap.get("status");
            List<String> dirList = (List<String>) resultMap.get("dirList");
            if (!status) {
                return JsonResult.error("服务器解压文件出错");
            }
            log.info("dirList: {}", JSON.toJSONString(dirList));
            for (String path : dirList) {
                if (path.contains("unZipDir")) {
                    list.add(path);
                    String substring = path.substring(14);
                    pathList.add(substring);
                }
            }

            List<DataSheet> dataSheetList = JSONObject.parseArray(dataSheetJson, DataSheet.class);
            log.info("dataSheetList: {}", dataSheetList);
            //匹配excel路径
            String distSftpFilePath = "gis/projectData/" + TimeSimpleUtil.getTimeStr() + "";
            for (DataSheet dataSheet : dataSheetList) {
                for (String path : pathList) {
                    if (path.contains(dataSheet.getFilePath())) {
                        //移动文件
                        SFTPUtil.copyFile(path, "/opt/" + distSftpFilePath);
                        successPath.add(dataSheet.getFilePath());
                    } else {
                        errPath.add(dataSheet.getFilePath());
                    }
                }
            }
            List<ProjectData> dataList = new ArrayList<>();
            List<ProjectData> projectDataList = new ArrayList<>();
            //匹配成功的
            List<String> listSuc = new ArrayList<>(successPath);
            for (int i = 0; i < listSuc.size(); i++) {
                String path = listSuc.get(i);
                String[] split = path.split("/");
                String name = split[split.length - 1];
                String[] typeSplit = name.split("\\.");
                ProjectData pt = new ProjectData();
                pt.setId(i + 1);
                pt.setFilePath(path);
                pt.setFileName(name);
                pt.setType(typeSplit[typeSplit.length - 1]);
                pt.setRecordState("有");
                pt.setFileStatus("有");
                pt.setContrastResult("成功");
                pt.setFileUrl(fileUrl + "/" + distSftpFilePath + "/" + name);
                projectDataList.add(pt);
                dataList.add(pt);
                //int insert = projectDataMapper.insert(pt);
            }
            //匹配不上的路径
            Set<String> difference = difference(errPath, successPath);
            List<String> listErr = new ArrayList<>(difference);
            for (int i = 0; i < listErr.size(); i++) {
                String path = listErr.get(i);
                String[] split = path.split("/");
                String name = split[split.length - 1];
                String[] typeSplit = name.split("\\.");
                ProjectData pt = new ProjectData();
                pt.setId(listSuc.size() + i + 1);
                pt.setFilePath(path);
                pt.setFileName(name);
                pt.setType(typeSplit[typeSplit.length - 1]);
                pt.setRecordState("有");
                pt.setFileStatus("无");
                pt.setContrastResult("失败");
                projectDataList.add(pt);
            }
            result.put("projectDataList", projectDataList);
            String jsonPath = JSON.toJSONString(pathList);
            //存放redis
            //verify:
            String verify = UUIDUtil.getRandNum(6);
            redisUtils.setCacheObject("jsonPath", jsonPath, 120, TimeUnit.MINUTES);
            redisUtils.setCacheObject("dataList", JSON.toJSONString(dataList), 120, TimeUnit.MINUTES);
            redisUtils.setCacheObject("verify:upload", verify, 120, TimeUnit.MINUTES);
            //redisUtils;
            result.put("verify", verify);
            return JsonResult.success(result);
        } catch (Exception e) {
            log.error("文件上传失败==ProjectServiceImpl==method:upload==errMsg: {}", e.getMessage());
            return JsonResult.error(e.getMessage());
        }
    }*/


    /****
     * 项目资料上传
     * @param file
     * @param sign 标识
     * @return
     */
    /*@Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult upload(MultipartFile file, String sign) {
        log.info("项目资料上传==ProjectServiceImpl==method:upload==文件名: {}, 文件大小: {}", file.getOriginalFilename(), file.getSize());
        //返回前端展示的相对路径
        Set<String> successPath = new HashSet<>();
        Set<String> errPath = new HashSet<>();
        Map<String, Object> result = new HashMap<>();
        //存放解压成功后的路径
        Set<String> pathList = new HashSet<>();
        Set<String> list = new HashSet<>();
        try {
            String timeStr = TimeSimpleUtil.getTimeStr();
            String dir = "/opt/upload/" + timeStr + "/";
            //创建文件夹
            if (!SFTPUtil.isExistDir(dir)) {
                Boolean mkdir = SFTPUtil.mkdir(dir);
                if (!mkdir) {
                    return JsonResult.error("服务器创建文件夹错误");
                }
            }
            //文件上传到服务器
            File newFile = this.multipartFileToFile(file);
            Boolean aBoolean = SFTPUtil.uploadFile(dir, newFile);
            delteTempFile(newFile);
            if (!aBoolean) {
                return JsonResult.error("上传失败");
            }
            //创建解压文件夹
            String unZipDir = "/opt/upload/unZipDir/" + TimeSimpleUtil.getTimeStr();
            if (!SFTPUtil.isExistDir(unZipDir)) {
                Boolean mkdir1 = SFTPUtil.mkdir(unZipDir);
                if (!mkdir1) {
                    return JsonResult.error("服务器创建解压文件夹错误");
                }
            }
            //解压文件
            Map<String, Object> resultMap = ExtractUtils.remoteZipToFile(dir, file.getOriginalFilename(), unZipDir);
            Boolean status = (Boolean) resultMap.get("status");
            List<String> dirList = (List<String>) resultMap.get("dirList");
            if (!status) {
                return JsonResult.error("服务器解压文件出错");
            }
            log.info("dirList: {}", JSON.toJSONString(dirList));
            for (String path : dirList) {
                if (path.contains("unZipDir")) {
                    list.add(path);
                    String substring = path.substring(14);
                    pathList.add(substring);
                }
            }
            //获取redis存放的数据 匹配Excel导入的文件路径
            String dataSheetJson = redisUtils.getCacheMapValue("dataSheetList", sign);
            if (StringUtils.isEmpty(dataSheetJson)) {
                return JsonResult.error("请重新上传Excel");
            }
            List<DataSheet> dataSheetList = JSONObject.parseArray(dataSheetJson, DataSheet.class);
            log.info("dataSheetList: {}", dataSheetList);
            //匹配excel路径
            String distSftpFilePath = "gis/projectData/" + TimeSimpleUtil.getTimeStr() + "";
            for (DataSheet dataSheet : dataSheetList) {
                for (String path : pathList) {
                    if (path.contains(dataSheet.getFilePath())) {
                        //移动文件
                        SFTPUtil.copyFile(path, "/opt/" + distSftpFilePath);
                        successPath.add(dataSheet.getFilePath());
                    } else {
                        errPath.add(dataSheet.getFilePath());
                    }
                }
            }
            List<ProjectData> dataList = new ArrayList<>();
            List<ProjectData> projectDataList = new ArrayList<>();
            //匹配成功的
            List<String> listSuc = new ArrayList<>(successPath);
            for (int i = 0; i < listSuc.size(); i++) {
                String path = listSuc.get(i);
                String[] split = path.split("/");
                String name = split[split.length - 1];
                String[] typeSplit = name.split("\\.");
                ProjectData pt = new ProjectData();
                pt.setId(i + 1);
                pt.setFilePath(path);
                pt.setFileName(name);
                pt.setType(typeSplit[typeSplit.length - 1]);
                pt.setRecordState("有");
                pt.setFileStatus("有");
                pt.setContrastResult("成功");
                pt.setFileUrl(fileUrl + "/" + distSftpFilePath + "/" + name);
                projectDataList.add(pt);
                dataList.add(pt);
                //int insert = projectDataMapper.insert(pt);
            }
            //匹配不上的路径
            Set<String> difference = difference(errPath, successPath);
            List<String> listErr = new ArrayList<>(difference);
            for (int i = 0; i < listErr.size(); i++) {
                String path = listErr.get(i);
                String[] split = path.split("/");
                String name = split[split.length - 1];
                String[] typeSplit = name.split("\\.");
                ProjectData pt = new ProjectData();
                pt.setId(listSuc.size() + i + 1);
                pt.setFilePath(path);
                pt.setFileName(name);
                pt.setType(typeSplit[typeSplit.length - 1]);
                pt.setRecordState("有");
                pt.setFileStatus("无");
                pt.setContrastResult("失败");
                projectDataList.add(pt);
            }
            result.put("projectDataList", projectDataList);
            String jsonPath = JSON.toJSONString(pathList);
            //存放redis
            //verify:
            String verify = UUIDUtil.getRandNum(6);
            redisUtils.setCacheObject("jsonPath", jsonPath, 120, TimeUnit.MINUTES);
            redisUtils.setCacheObject("dataList", JSON.toJSONString(dataList), 120, TimeUnit.MINUTES);
            redisUtils.setCacheObject("verify:upload", verify, 120, TimeUnit.MINUTES);
            //redisUtils;
            result.put("verify", verify);
            return JsonResult.success(result);
        } catch (Exception e) {
            log.error("文件上传失败==ProjectServiceImpl==method:upload==errMsg: {}", e.getMessage());
            return JsonResult.error(e.getMessage());
        }
    }*/


    /***
     * 项目资料上传 windows版本的
     */
    /*@Override
    public JsonResult upload(MultipartFile file, String sign) {
        //保存zip
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String format = sdf.format(new Date());
        String path = "C://service_system//upload//" + format + "//" + file.getOriginalFilename();
        //返回前端展示的相对路径
        Set<String> successPath = new HashSet<>();
        Set<String> errPath = new HashSet<>();
        Map<String, Object> resultMap = new HashMap<>();
        try {
            MultipartFile dataFile = file;
            File newFile = new File(path);
            if (!newFile.exists()) {
                newFile.mkdirs();
            }
            //保存压缩包
            dataFile.transferTo(newFile);
            //解压缩
            String target = "C://service_system//upload//" + format + "//unzip//";
            File targetFile = new File(target);
            if (!targetFile.exists()) {
                targetFile.mkdirs();
            }
            //解压
            JsonResult result = FileUtils.decompressZip(newFile.getPath(), target);
            if (result.getCode() == 0) {
                //解压成功后匹配Excel导入的文件路径
                String dataSheetJson = redisUtils.getCacheMapValue("dataSheetList", sign);
                if (StringUtils.isEmpty(dataSheetJson)) {
                    return JsonResult.error("请重新上传Excel");
                }
                List<DataSheet> dataSheetList = JSONObject.parseArray(dataSheetJson, DataSheet.class);
                log.info("dataSheetList: {}", dataSheetList);
                //解压成功的路径
                String stringPath = (String) result.getData();
                List<String> pathList = JSONObject.parseArray(stringPath, String.class);
                for (DataSheet dataSheet : dataSheetList) {
                    for (String url : pathList) {
                        if (url.contains(dataSheet.getFilePath())) {
                            successPath.add(dataSheet.getFilePath());
                            //移动到指定文件夹
                            File targetPath = new File("D://upload//A//");
                            if (!targetPath.exists()) {
                                targetPath.mkdirs();
                            }
                            boolean b = FileUtils.removeFile(url, targetPath.getPath());
                            if (!b) {
                                return JsonResult.error("保存文件出错了");
                            }
                        } else {
                            errPath.add(dataSheet.getFilePath());
                        }
                    }
                }

            }
            resultMap.put("successPath", successPath);
            resultMap.put("errPath", errPath);
            return JsonResult.success(resultMap);
        } catch (Exception e) {
            log.error("文件上传失败==message:{}", e.getMessage());
            return JsonResult.error(e.getMessage());
        }


    }*/


    /***
     * 匹配上传资料
     * @return
     */
    @Override
    public JsonResult matching(String verify) {
        Map<String, Object> result = new HashMap<>();
        try {

            String jsonSheetList = redisUtils.getCacheMapValue("sheetList", verify);
            if (StringUtils.isEmpty(jsonSheetList)) {
                return JsonResult.error("请重新上传资料");
            }
            List<ProjectData> projectDataList = new ArrayList<>();
            Integer projectId = redisUtils.getCacheObject("projectId");
            List<DataSheet> dataSheetList = JSONObject.parseArray(jsonSheetList, DataSheet.class);
            for (DataSheet sheet : dataSheetList) {
                ProjectData projectData = new ProjectData();
                BeanUtils.copyProperties(sheet, projectData);
                projectDataList.add(projectData);
            }
            for (ProjectData projectData : projectDataList) {
                projectData.setProjectId(projectId);
                projectDataMapper.insert(projectData);
            }
            String verifyMatching = UUIDUtil.getRandNum(6);
            redisUtils.setCacheObject("verify:matching", verifyMatching, 120, TimeUnit.MINUTES);
            result.put("verify", verifyMatching);
            return JsonResult.success(result);
        } catch (Exception e) {
            log.error("匹配上传资料失败==ProjectServiceImpl==method:matching==errMsg: {}", e.getMessage());
            return JsonResult.error(e.getMessage());
        }

    }


    /****
     * 项目资料上传完毕,清理零时文件
     * @return
     */
    @Override
    public JsonResult destroy(String verify) {
        try {
            String verifyMatching = redisUtils.getCacheObject("verify:matching");
            if (StringUtils.isEmpty(verifyMatching)) {
                return JsonResult.error("请重新上传资料");
            }
            if (!verifyMatching.equals(verify)) {
                return JsonResult.error("verify错误");
            }

            return JsonResult.success();
        } catch (Exception e) {
            return JsonResult.error(e.getMessage());
        }

    }


    /****
     * 上传项目资料
     * @return
     */
    @Override
    public JsonResult uploadProjectInfo(MultipartFile file, Integer projectId) {
        try {
            String filePath = fileTemplate.uploadFile(file);
            if (StringUtils.isEmpty(filePath)) {
                return JsonResult.error("上传失败");
            }
            String fastDFSPath = "/opt/fastdfs/fdfs_storage/data/";
            Map<String, String> paramMap = subFilePath(filePath);
            String fileName = paramMap.get("fileName");
            String relativePath = paramMap.get("path");
            String fileUrl = fastDFSPath + relativePath;
            String fileUri = fileUrl + "," + fileName;
            Map<String, String> param = new HashMap<>();
            param.put("fileUrl", fileUrl);
            param.put("fileName", fileName);
            param.put("projectId", String.valueOf(projectId));
            // 两个线程的线程池
            ExecutorService executor = Executors.newFixedThreadPool(2);
            CompletableFuture<String> future = CompletableFuture.supplyAsync(new Supplier<String>() {
                @Override
                public String get() {
                    try {
                        unzip(param);
                    } catch (Exception e) {
                        return null;
                    }
                    return "success";
                }
            }, executor);
            return JsonResult.success("上传成功，服务器解析文件中");
        } catch (Exception e) {
            log.error("匹配上传资料失败==ProjectServiceImpl==method:uploadProjectInfo==errMsg: {}", e.getMessage());
            return JsonResult.error(e.getMessage());
        }
    }


    public void unzip(Map<String, String> param) {
        SqlSession session = null;
        log.info("解压上传的项目资料: {}", param);
        String file_name = param.get("fileName");
        String file_url = param.get("fileUrl");
        Integer projectId = Integer.parseInt(param.get("projectId"));
        Integer.parseInt(param.get("projectId"));
        String randomString = UUIDUtil.getRandomString(8); //随机文件夹
        String dataDir = "/opt/upload/unZipDir/" + TimeSimpleUtil.getTimeStr() + "/";
        String unZipDir = dataDir + randomString;
        try {
            if (!SFTPUtil.isExistDir(dataDir)) {
                Boolean mkdir1 = SFTPUtil.mkdir(dataDir);
                if (!mkdir1) {
                    log.error("解压上传的项目资料==服务器创建解压[" + mkdir1 + "]文件夹错误");
                    return;
                }
            }
            if (!SFTPUtil.isExistDir(unZipDir)) {
                Boolean mkdir1 = SFTPUtil.mkdir(unZipDir);
                if (!mkdir1) {
                    log.error("解压上传的项目资料==服务器创建解压[" + mkdir1 + "]文件夹错误");
                    return;
                }
            }

            //解压文件
            Map<String, Object> resultMap = ExtractUtils.remoteZipToFile(file_url, file_name, unZipDir);
            Boolean status = (Boolean) resultMap.get("status");
            List<String> dirList = (List<String>) resultMap.get("dirList");
            if (!status) {
                log.error("解压上传的项目资料==服务器创建解压[" + status + "]文件夹错误");
                return;
            }

            //解压后的路径
            log.info("解压成功，插入数据库中");
            List<String> filePathList = conversion2(dirList, unZipDir);
            if (filePathList != null && !filePathList.isEmpty()) {
                List<ProjectData> projectDataList = new ArrayList<>();
                for (int i = 0; i < filePathList.size(); i++) {
                    String file = filePathList.get(i);
                    String[] split = file.split("/");
                    String fileName = split[split.length - 1];
                    ProjectData projectData = new ProjectData();
                    projectData.setAuthority(38);//默认数据权限
                    projectData.setIdentity(1);//默认身份权限
                    projectData.setFileName(fileName);
                    projectData.setFileAlias(fileName.split("\\.")[0]);
                    //projectData.setFileUrl(fileUrl + file.replace("/opt/upload/unZipDir", ""));
                    projectData.setFileUrl(file);
                    projectData.setFilePath(this.constructionPath(file));
                    projectData.setProjectId(projectId);
                    projectData.setCreateTime(new Date());
                    projectDataList.add(projectData);
                }

                log.info("projectDataList: {}", projectDataList.size());
                String tem = "/opt/upload/file/" + TimeSimpleUtil.getTimeStr() + "/";
                if (!SFTPUtil.isExistDir(tem)) {
                    Boolean mkdir = SFTPUtil.mkdir(tem);
                    if (!mkdir) {
                        log.error("解压上传的项目资料==服务器创建解压[" + tem + "]文件夹错误");
                        return;
                    }
                }

                for (ProjectData projectData : projectDataList) {
                    String fileUrl = projectData.getFileUrl();
                    String[] split = fileUrl.split("\\.");
                    String uUid = UUIDUtil.getUUid();
                    String tarPath = tem + uUid + "." + split[split.length - 1];
                    projectData.setFileUrl("/group/M00/" + TimeSimpleUtil.getTimeStr() + "/" + uUid + "." + split[split.length - 1]);
                    //SFTPUtil.copyFile(fileUrl, tarPath);
                    //移动文件 移动命令
                    String moveCmd = "mv '" + fileUrl + "' " + tarPath;
                    log.info("moveCmd :{}", moveCmd);
                    SFTPUtil.exec(null, moveCmd);
                }

                projectDataMapper.btchInsert(projectDataList);
            }

            //删除压缩文件 compressedFile
            SFTPUtil.delete(file_url, file_name);
            log.info("插入数据库中成功");
        } catch (Exception e) {
            log.error("解压文件失败==ProjectServiceImpl==method:unzip==errMsg: {}", e.getMessage());
        }


    }


    /***
     * 解压上传之后的项目资料
     */
    //@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
//    public void unzip(Map<String, String> param) {
//        log.info("解压上传的项目资料: {}", param);
//        String file_name = param.get("fileName");
//        String file_url = param.get("fileUrl");
//        Integer projectId = Integer.parseInt(param.get("projectId"));
//        Integer.parseInt(param.get("projectId"));
//        String randomString = UUIDUtil.getRandomString(8); //随机文件夹
//        String unZipDir = "/opt/upload/unZipDir/" + TimeSimpleUtil.getTimeStr() + "/" + randomString;
//        if (!SFTPUtil.isExistDir(unZipDir)) {
//            Boolean mkdir1 = SFTPUtil.mkdir(unZipDir);
//            if (!mkdir1) {
//                log.info("解压上传的项目资料==服务器创建解压文件夹错误");
//                return;
//            }
//        }
//        //解压文件
//        Map<String, Object> resultMap = ExtractUtils.remoteZipToFile(file_url, file_name, unZipDir);
//        Boolean status = (Boolean) resultMap.get("status");
//        List<String> dirList = (List<String>) resultMap.get("dirList");
//        if (!status) {
//            log.error("解压上传的项目资料==服务器解压文件出错");
//            return;
//        }
//        //解压后的路径
//        log.info("解压成功，插入数据库中");
//        List<String> filePathList = conversion2(dirList, unZipDir);
//        List<ProjectData> projectDataList = new ArrayList<>();
//        for (String file : filePathList) {
//            String[] split = file.split("/");
//            ProjectData projectData = new ProjectData();
//            projectData.setAuthority(38);//默认数据权限
//            projectData.setFileName(split[split.length - 1]);
//            projectData.setFileUrl(fileUrl + file);
//            projectData.setFilePath(this.constructionPath(file));
//            projectData.setProjectId(projectId);
//            projectData.setCreateTime(new Date());
//            projectDataList.add(projectData);
////            projectDataMapper.insert(projectData);
//
//        }
//        log.info("projectDataList: {}", projectDataList.size());
////        projectDataMapper.btchInsert(projectDataList);
//
//        String sql = "INSERT INTO project_data (file_path,file_name,authority,file_url,project_id,create_time) VALUES(?,?,?,?,?,?)";
//        List<Object[]> batchArgs = new ArrayList<Object[]>();
//        for (ProjectData pd : projectDataList) {
//            batchArgs.add(new Object[]{pd.getFilePath(), pd.getFileName(), pd.getAuthority(), pd.getFileUrl(), pd.getProjectId(), pd.getCreateTime()});
//        }
//        System.out.println(" batchArgs.size()" +  batchArgs.size());
//        jdbcTemplate.batchUpdate(sql, batchArgs);
//        log.info("插入数据库中成功");
//    }


    /****
     * 构造路径
     * @param name
     * @return
     */
    public String constructionPath(String name) {
        System.out.println("constructionPath==name: " + name);
        String[] file = name.split("/");
        StringBuffer sb = new StringBuffer();
        for (int i = 6; i < file.length; i++) {
            String str = file[i];
            if (i == file.length - 1) {
            } else {
                sb.append(str).append("/");
            }
        }
        String result = sb.toString();
        if (result.endsWith("/")) {
            result = result.substring(0, result.length() - 1);
        }
        return result;
    }

    public static void main(String[] args) {
        String str = "/opt/upload/unZipDir/20210907/N0Jjz9bx/报告1青海省都兰县小红土湾地区铜锡多金属矿预查报告/报告1.xls";
        ProjectServiceImpl projectService = new ProjectServiceImpl();

        String s = projectService.constructionPath(str);
        System.out.println(s);

    }


    /****
     * 组合解压后的文件路径
     * @param dirList
     * @param sign
     * @return
     */
    private List<String> conversion(List<String> dirList, String sign) {
        List<String> result = new ArrayList<>();
        List<String> temList = new ArrayList<>();
        List<String> temList2 = new ArrayList<>();
        for (String path : dirList) {
            if (path.contains(sign) && !path.endsWith("/")) {
                temList.add(path);
            }
        }
        if (temList.isEmpty()) {
            return null;
        }
        for (String s : temList) {
            String tem = s.substring(0, s.indexOf(":"));
            String substring = s.substring(tem.length() + 1, s.length());
            temList2.add(substring);
        }

        for (String s : temList2) {
            String trim = s.trim();
            if (trim.startsWith("//")) {
                trim = trim.substring(1, trim.length());
            }
            if (!trim.endsWith("/")) {
                result.add(trim);
            }
        }
        List<String> list = new ArrayList<>();
        for (String s : result) {
            String substring = s.substring(sign.length() + 1, s.length());
            list.add(substring);
        }
        return list;
    }


    private List<String> conversion2(List<String> dirList, String sign) {
        System.out.println("dirList: " + dirList);
        System.out.println("sign: " + sign);
        List<String> result = new ArrayList<>();
        List<String> temList = new ArrayList<>();
        List<String> temList2 = new ArrayList<>();
        for (String path : dirList) {
            if (path.contains(sign) && !path.endsWith("/")) {
                temList.add(path);
            }
        }
        if (temList.isEmpty()) {
            return null;
        }
        for (String s : temList) {
            String tem = s.substring(0, s.indexOf(":"));
            String substring = s.substring(tem.length() + 1, s.length());
            temList2.add(substring);
        }

        for (String s : temList2) {
            String trim = s.trim();
            if (trim.startsWith("//")) {
                trim = trim.substring(1, trim.length());
            }
            if (!trim.endsWith("/")) {
                result.add(trim);
            }
        }
        return result;
    }

    /***
     * 截取文件路径
     * @param source
     * @return
     */
    public Map<String, String> subFilePath(String source) {
        log.info("sourceFilePath: {}", source);
        Map<String, String> result = new HashMap<>();
        String[] split = source.split("/");
        StringBuffer sb = new StringBuffer();
        for (int i = 3; i < split.length; i++) {
            String s = split[i];
            if (i <= split.length - 2) {
                sb.append(s).append("/");
            }
            if (i == split.length - 1) {
                log.info("fileName: {}", split[i]);
                result.put("fileName", split[i]);
            }
        }
        result.put("path", sb.toString());
        return result;
    }


}
